package utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Map;

public class HttpClientUtils {
    private static final CloseableHttpClient httpClient;
    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

    static {
        httpClient = HttpClientBuilder.create().build();

    }

    //url
    public static String urlBuild(String url, Map<String, String> params) throws URISyntaxException {
        URIBuilder uriBuilder = new URIBuilder(url);
        if (params != null) {
            for (String key : params.keySet()) {
                uriBuilder.addParameter(key, params.get(key));
            }
        }
        logger.info(uriBuilder.build().toString());
        return uriBuilder.build().toString();

    }

    //响应对象
    public static ResponseData responseDataBuild(CloseableHttpResponse response) throws IOException {
        ResponseData responseData = new ResponseData();
        responseData.setStatusCode(response.getStatusLine().getStatusCode());
        String s = EntityUtils.toString(response.getEntity());
        logger.info(s);
        if (s != null && s.startsWith("{")) {
            logger.info("响应体为json数据");
            responseData.setBody(JSONObject.parseObject(s));
        } else {
            logger.warn("响应体不为jon数据");
        }

        return responseData;

    }

    //get
    public static ResponseData get(String url, Map<String, String> params) throws Exception {
        logger.info("url={}  params={}",url,params);
        //url
        String newUrl = urlBuild(url, params);
        //设置请求,获取响应对象
        HttpGet httpGet = new HttpGet(newUrl);
        //释放资源
        return responseDataBuild(httpClient.execute(httpGet));
    }

    public static ResponseData get(String url) throws Exception {
        return get(url, null);
    }


    //post-form
    public static ResponseData post(String url, Map<String, String> params, Map<String, String> formParams) throws Exception {
        logger.info("url={}  params={} formParams={}",url,params,formParams);
        //url
        String newUrl = urlBuild(url, params);
        //设置请求体,获取响应对象
        HttpPost httpPost = new HttpPost(newUrl);
        if (formParams != null) {
            ArrayList<NameValuePair> paramList = new ArrayList<>();
            for (String key : formParams.keySet()) {
                paramList.add(new BasicNameValuePair(key, formParams.get(key)));
            }
            logger.info(String.valueOf(paramList));
            httpPost.setEntity(new UrlEncodedFormEntity(paramList));
        }
        CloseableHttpResponse response = httpClient.execute(httpPost);
        ResponseData responseData = responseDataBuild(response);
        response.close();
        return responseData;
    }

    public static ResponseData post(String url, Map<String, String> formParams) throws Exception {
        return post(url, null, formParams);
    }

    //post请求,可以传递文件数据和普通表表单数据
    public static ResponseData postFile(String url, Map<String, String> formParams,Map<String, String> fileParams) throws Exception {
        logger.info("url={}  formParams={} fileParams={} ",url,formParams,fileParams);
        HttpPost httpPost = new HttpPost(url);
        //设置请求体,获取响应对象
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        //普通表单
        if (formParams != null) {
            for (String key : formParams.keySet()) {
                builder.addPart(key,new StringBody(formParams.get(key), ContentType.MULTIPART_FORM_DATA));
            }
        }
        //设置文件数据
        if (fileParams != null) {
            for (String key : fileParams.keySet()) {
                builder.addBinaryBody(key,new File(fileParams.get(key)));
            }
        }
        HttpEntity build = builder.build();
        httpPost.setEntity(build);
        //发送请求
        CloseableHttpResponse response = httpClient.execute(httpPost);
        ResponseData responseData = responseDataBuild(response);
        response.close();
        return responseData;
    }
}
